import type { RouteRecordRaw, RouteComponent } from 'vue-router'
import { listRoutes } from '@/api/menu/menu_api_index.ts'
import { defineStore } from 'pinia'
// import { constantRoutes } from '@/router'
import {pinia} from '@/store/storeIndex'
import { ref } from 'vue'
import { staticShowRoutes } from '@/routes/static_routes'

//todo: 优化
// async 中的函数，不应该返回具体的值
// 而是仅作为 计算 status的方法，但是可以返回 promise对象

//VITE_ALIAS_VIEWS_VUE_ABS_PATH_PATTERN 为别名，编译阶段会替换成相应字符串
// const modules = import.meta.glob('VITE_ALIAS_VIEWS_VUE_ABS_PATH_PATTERN', {
//     eager: true,
//     import: 'default',
// })
const modules = import.meta.glob('@/views/**/**_index.vue', {
    // eager: true,
    import: 'default',
})
console.log('modules', modules)

// const Layout = () => import('D:/Front_End/Gitee/gui_gu_admin_combine_ts/src/layout/index.vue')
const Layout = () => import('@/views/layout/layout_index.vue')

console.log('Layout', Layout, typeof Layout)
// for (const e of modules) {
//     myUtils.logObj('e', ' in modules ')
// }
export function listModudels() {
    for (const path in modules) {
        //myUtils.log(modules[path])
        console.log(path, modules[path])
        // console.log(typeof path)
        // console.log(typeof modules[path])
    }
}

/**
 * Use meta.role to determine if the current user has permission
 * @param roles 用户角色集合
 * @param route 路由
 * @returns
 */
const hasPermission = (roles: string[], route: RouteRecordRaw) => {
    if (route.meta?.roles) {
        if (roles.includes('ROOT')) {
            return true
        }
        return roles.some((role) => {
            return (route.meta?.roles as string[]).includes(role)
        })
    }
    return false
}

/**
 * 递归过滤有权限的异步(动态)路由
 * 过滤有两层含义：
 * 1. 按roles的权限过滤
 * 2. 是否确实存在相应的 vue文件，导出形成的组件，即上面的modules，确实包含了对应的组件
 *
 * @param routes 接口返回的异步(动态)路由
 * @param roles 用户角色集合
 * @returns 返回用户有权限的异步(动态)路由
 */
const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
    const asyncRoutes: RouteRecordRaw[] = []
    console.log('response routes', routes)

    routes.forEach((route) => {
        const tmpRoute = { ...route } //浅拷贝
        //把 route.path 也复制给 tmpRoute.name
        //todo: name 是否会重复?
        if (!route.name) {
            tmpRoute.name = route.path
        }
        // 判断路由信息中，是否包含role,从而判断该路由是否 为允许路由
        if (hasPermission(roles, tmpRoute)) {
            //console.log('tmpRoute', tmpRoute)
            //处理 component Property
            if (tmpRoute.component?.toString() == 'Layout') {
                //console.log('tmpRoute', tmpRoute)
                //console.log('tmpRoute.component?.toString()', tmpRoute.component?.toString())
                tmpRoute.component = Layout
                //console.log('type of tmpRoute.component', typeof tmpRoute.component)
            } else {
                // const path = `/src/views/${tmpRoute.component}.vue`
                //此时的component属性还是后台返回的字符串：
                //如：component: system/user/index
                const path = `${VITE_GLOBAL_VAR_VIEWS_REL_PATH}/${tmpRoute.component}.vue`
                // const path = 'VITE_GLOBAL_VIEWS_PATH/' + tmpRoute.component + '.vue'
                const component = modules[path]
                // console.log('path =', path)
                // console.log('component =', component)
                // console.log('component =', component)
                if (component) {
                    // console.log('path =', path)
                    // console.log('component =', component)
                    // console.log('typeof component =', typeof component)
                    tmpRoute.component = component
                } else {
                    tmpRoute.component = modules[`/src/views/error-page/404.vue`] as RouteComponent
                }
            }

            if (tmpRoute.children) {
                tmpRoute.children = filterAsyncRoutes(tmpRoute.children, roles)
            }
            asyncRoutes.push(tmpRoute)
        }
    })
    return asyncRoutes
}

export const useAsyncRoutesStore = defineStore('permission', () => {
    //state
    // routes: 动 静 路由都包括

    /** 所有路由的响应式对象，包括动态和静态路由,为界面组件提供数据源*/
    const allRoutes = ref<RouteRecordRaw[]>([])
    const dynamicRoutes = ref<RouteRecordRaw[]>([])

    /**
     * get表示: routes不为空，则直接返回route,为空，则生成routes再返回
     * @param roles 如['Root','normal-user']
     * @returns 所有路由，包含动静
     */
    // async function getAllRoutes(roles: string[]) {
    //     dynamicRoutes.value = await getDynamicRoutes(roles)
    //     allRoutes.value = constantRoutes.concat(dynamicRoutes.value)
    //     return allRoutes.value
    // }

    /**
     * 生成全部路由的响应式对象，为页面组件提供数据源，即使已经存在，也重新生成
     * @param roles
     * @returns
     */
    async function generateAllRoutes(roles: string[] = []) {
        dynamicRoutes.value = await getDynamicRoutes(roles)
        // allRoutes.value = staticRoutes.concat(dynamicRoutes.value)
        allRoutes.value = staticShowRoutes.concat(dynamicRoutes.value)

        return allRoutes.value
    }

    /**
     * 有动态路由则直接返回，无则生成动态路由
     * @param roles
     * @returns
     */
    async function getDynamicRoutes(roles: string[] | undefined) {
        console.log('in getDynamicRoutes');
        console.log('dynamicRoutes.value',dynamicRoutes.value);
        console.log('roles',roles);
        if (!dynamicRoutes.value.length && roles) {
            dynamicRoutes.value = await generateDynamicRoutes(roles)
        }
        return dynamicRoutes.value
    }
    /**
     * 生成动态路由，即使已经存在，也重新生成
     *
     * @param roles 用户角色集合
     * @returns
     */
    function generateDynamicRoutes(roles: string[]) {
        return new Promise<RouteRecordRaw[]>((resolve, reject) => {
            console.log('in generateDynamicRoutes  1111');
            //接口获取所有路由
            listRoutes()
                .then(({ data: asyncRoutes }: { data: RouteRecordRaw[] }) => {
                    // console.log('asyncRoutes in  generateDynamicRoutes=',asyncRoutes);
                    console.log('in generateDynamicRoutes  2222');
                    // 根据角色获取有访问权限的路由
                    const dynamicRoutesWithComponents = filterAsyncRoutes(asyncRoutes, roles)
                    console.log('asyncRoutesWithComponents', dynamicRoutesWithComponents)
                    //解析生成的动态路由，赋值给动态路由响应式对象
                    dynamicRoutes.value = dynamicRoutesWithComponents
                    // console.log('dynamicRoutesWithComponents =',dynamicRoutesWithComponents);

                     //重置 allRoutes
                     //allRoutes.value = staticRoutes.concat(dynamicRoutes.value)     
                     allRoutes.value = staticShowRoutes.concat(dynamicRoutes.value)   

                    resolve(dynamicRoutesWithComponents)
                })
                .catch((error: any) => {
                    reject(error)
                })
        })
    }

    return {
        allRoutes,
        getDynamicRoutes,
        generateAllRoutes,
        generateDynamicRoutes,
    }
})

//非setup环境使用
// 非setup
export function useAsyncRoutesStoreHook() {
    return useAsyncRoutesStore(pinia)
}